﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using SourceGrid;

namespace iPdf
{
    partial class TataGrid
    {
        //controllers and editors
        KeyController keyController;
        ContextMenuController popupMenuController;
        CheckBoxController checkBoxController;
        ErrorController errorController;
        FilePathEditor destinatinCellEditor;
        FormatComboxEditor formatCellEditor;
        SourceGrid.Cells.Editors.TextBox passwordEditor;
       

        TooltipController sourceCellTooltip;
        TooltipController destinationCellTooltip;
        SourceGrid.Cells.Controllers.ToolTipText columnHeaderTooltip;

        private void InitializeControllerAndEditor()
        {
            keyController = new KeyController();
            popupMenuController = new ContextMenuController();
            errorController = new ErrorController();

            passwordEditor = new PasswordEditor(typeof(string));
            passwordEditor.Control.Font = editorFont;

            destinatinCellEditor = new FilePathEditor(Global.PdfExt);
            destinatinCellEditor.Control.Font = editorFont;
            

            checkBoxController = new CheckBoxController();

            formatCellEditor = new FormatComboxEditor();

            sourceCellTooltip = new TooltipController();
            sourceCellTooltip.ToolTipIcon = ToolTipIcon.Info;
            sourceCellTooltip.ToolTipTitle = Source.Name + global::iPdf.Properties.Resources.SourceCellTip;

            destinationCellTooltip = new TooltipController();
            destinationCellTooltip.ToolTipIcon = ToolTipIcon.Info;
            destinationCellTooltip.ToolTipTitle = Destination.Name + global::iPdf.Properties.Resources.DestinationCellTip;

            columnHeaderTooltip = new SourceGrid.Cells.Controllers.ToolTipText();
        }

        #region Controllers and editors
        private class KeyController : SourceGrid.Cells.Controllers.ControllerBase
        {
            private bool enabled = true;

            public bool Enabled
            {
                set
                {
                    enabled = value;
                }
            }

            public override void OnKeyDown(SourceGrid.CellContext sender, KeyEventArgs e)
            {
                if (enabled == false)
                {
                    return;
                }

                base.OnKeyDown(sender, e);
                TataGrid grid = (TataGrid)sender.Grid;

                if (e.KeyCode == Keys.Delete)
                {
                    int rowPos = sender.Position.Row;
                    if (grid.Selection.IsSelectedRow(rowPos))
                    {
                        grid.RemoveSelection();
                    }
                    else
                    {
                        grid.RemoveRow(rowPos);
                    }

                    return;
                }

                if (e.KeyCode == Keys.A && e.Control == true
                    && e.Shift == false && e.Alt == false)
                {
                    grid.SelectAll();
                }
            }
        }

        private class ContextMenuController : SourceGrid.Cells.Controllers.ControllerBase
        {
            #region Fields
            private Elegant.Ui.ContextMenu PopUpMenu;
            private Elegant.Ui.Button RemoveMenuItem;
            private Elegant.Ui.Button InvertRemoveMenuItem;
            private Elegant.Ui.Separator Separator1;
            private Elegant.Ui.Button MoveUpMenuItem;
            private Elegant.Ui.Button MoveDownMenuItem;
            private Elegant.Ui.Separator Separator2;
            private Elegant.Ui.Button OpenMenuItem;
            private Elegant.Ui.Button OpenFileLocationMenuItem;
            private Elegant.Ui.Button SendAsEmailMenuItem;

            private SourceGrid.CellContext cellContext;
            private TataGrid grid;
            private int rowPos;
            private bool isSelected;
            private bool enabled = true;

            private delegate void OperationOnSelection();
            private delegate void OperationOnRow(int itemIndex);

            #endregion

            public bool Enabled
            {
                set
                {
                    enabled = value;
                }
            }

            public ContextMenuController()
            {
                InitializeComponent();
            }

            private void InitializeComponent()
            {
                this.PopUpMenu = new Elegant.Ui.ContextMenu();
                this.RemoveMenuItem = new Elegant.Ui.Button();
                this.InvertRemoveMenuItem = new Elegant.Ui.Button();
                this.Separator1 = new Elegant.Ui.Separator();
                this.MoveUpMenuItem = new Elegant.Ui.Button();
                this.MoveDownMenuItem = new Elegant.Ui.Button();
                this.Separator2 = new Elegant.Ui.Separator();
                this.OpenMenuItem = new Elegant.Ui.Button();
                this.OpenFileLocationMenuItem = new Elegant.Ui.Button();
                this.SendAsEmailMenuItem = new Elegant.Ui.Button();

                ((System.ComponentModel.ISupportInitialize)(this.PopUpMenu)).BeginInit();

                // 
                // PopUpMenu
                // 
                this.PopUpMenu.Items.AddRange(new System.Windows.Forms.Control[] {
                    this.RemoveMenuItem,
                    this.InvertRemoveMenuItem,
                    this.Separator1,
                    this.MoveUpMenuItem,
                    this.MoveDownMenuItem,
                    this.Separator2,
                    this.OpenMenuItem,
                    this.OpenFileLocationMenuItem,
                    this.SendAsEmailMenuItem
                    });
                this.PopUpMenu.PlacementMode = Elegant.Ui.PopupPlacementMode.Bottom;
                this.PopUpMenu.PlacementOffset = new System.Drawing.Size(265, 125);
                this.PopUpMenu.Size = new System.Drawing.Size(100, 100);
                this.PopUpMenu.Visible = true;
                // 
                // RemoveMenuItem
                // 
                this.RemoveMenuItem.Id = "d2c50305-55b8-462e-ba38-7454fbbdee40";
                this.RemoveMenuItem.Location = new System.Drawing.Point(2, 2);
                this.RemoveMenuItem.Name = "RemoveMenuItem";
                this.RemoveMenuItem.Size = new System.Drawing.Size(138, 23);
                this.RemoveMenuItem.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.Remove16)});
                this.RemoveMenuItem.TabIndex = 3;
                this.RemoveMenuItem.Text = "Remove";
                this.RemoveMenuItem.Click += new EventHandler(RemoveMenuItem_Click);
                // 
                // InvertRemoveMenuItem
                // 
                this.InvertRemoveMenuItem.Id = "ea4980a1-75aa-4eaf-b911-aa4ecb1b9d5d";
                this.InvertRemoveMenuItem.Location = new System.Drawing.Point(2, 25);
                this.InvertRemoveMenuItem.Name = "InvertRemoveMenuItem";
                this.InvertRemoveMenuItem.Size = new System.Drawing.Size(138, 23);
                this.InvertRemoveMenuItem.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.InvertRemove16)});
                this.InvertRemoveMenuItem.TabIndex = 4;
                this.InvertRemoveMenuItem.Text = "Invert Remove";
                this.InvertRemoveMenuItem.Click += new EventHandler(InvertRemoveMenuItem_Click);
                // 
                // Separator1
                // 
                this.Separator1.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
                this.Separator1.Id = "ed3a7b5b-db59-4a23-9964-e0e1ed7f0e6e";
                this.Separator1.Location = new System.Drawing.Point(0, 149);
                this.Separator1.Name = "Separator1";
                this.Separator1.Orientation = Elegant.Ui.SeparatorOrientation.Horizontal;
                this.Separator1.Size = new System.Drawing.Size(167, 5);
                this.Separator1.Text = "Separator1";
                // 
                // MoveUpMenuItem
                // 
                this.MoveUpMenuItem.Id = "cc79f896-0a8c-42cd-b98d-b0889ce48ca5";
                this.MoveUpMenuItem.Location = new System.Drawing.Point(2, 53);
                this.MoveUpMenuItem.Name = "MoveUpMenuItem";
                this.MoveUpMenuItem.Size = new System.Drawing.Size(138, 23);
                this.MoveUpMenuItem.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.MoveUp16)});
                this.MoveUpMenuItem.TabIndex = 6;
                this.MoveUpMenuItem.Text = "Move Up";
                this.MoveUpMenuItem.Click += new EventHandler(MoveUpMenuItem_Click);
                // 
                // MoveDownMenuItem
                // 
                this.MoveDownMenuItem.Id = "19a5823b-e64e-49ba-932e-e503582f2fea";
                this.MoveDownMenuItem.Location = new System.Drawing.Point(2, 76);
                this.MoveDownMenuItem.Name = "MoveDownMenuItem";
                this.MoveDownMenuItem.Size = new System.Drawing.Size(138, 23);
                this.MoveDownMenuItem.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
                    new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.MoveDown16)});
                this.MoveDownMenuItem.TabIndex = 8;
                this.MoveDownMenuItem.Text = "Move Down";
                this.MoveDownMenuItem.Click += new EventHandler(MoveDownMenuItem_Click);
                // 
                // Separator2
                // 
                this.Separator2.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
                this.Separator2.Id = "ed3a7b5b-db59-4a23-9964-e0e1ed7f0e6e";
                this.Separator2.Location = new System.Drawing.Point(0, 149);
                this.Separator2.Name = "Separator2";
                this.Separator2.Orientation = Elegant.Ui.SeparatorOrientation.Horizontal;
                this.Separator2.Size = new System.Drawing.Size(167, 5);
                this.Separator2.TabIndex = 8;
                this.Separator2.Text = "Separator2";
                // 
                // OpenFileMenuItem
                // 
                this.OpenMenuItem.Id = "0699d53d-e28e-4497-b7e8-ca788492dc54";
                this.OpenMenuItem.Location = new System.Drawing.Point(2, 76);
                this.OpenMenuItem.Name = "OpenMenuItem";
                this.OpenMenuItem.Size = new System.Drawing.Size(138, 23);
                this.OpenMenuItem.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
                    new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.OpenDocument16)});
                this.OpenMenuItem.TabIndex = 9;
                this.OpenMenuItem.Text = "Open";
                this.OpenMenuItem.Click += new EventHandler(OpenMenuItem_Click);
                // 
                // OpenFileLocationMenuItem
                // 
                this.OpenFileLocationMenuItem.Id = "67af924b-7e12-4852-87a7-d57c9898474f";
                this.OpenFileLocationMenuItem.Location = new System.Drawing.Point(2, 76);
                this.OpenFileLocationMenuItem.Name = "OpenFileLocationMenuItem";
                this.OpenFileLocationMenuItem.Size = new System.Drawing.Size(138, 23);
                this.OpenFileLocationMenuItem.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
                    new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.OpenFileLocation16)});
                this.OpenFileLocationMenuItem.TabIndex = 10;
                this.OpenFileLocationMenuItem.Text = "Open File Location";
                this.OpenFileLocationMenuItem.Click += new EventHandler(OpenFileLocationMenuItem_Click);

                // 
                // SendToMenuItem
                // 
                this.SendAsEmailMenuItem.Id = "67af924b-7e12-4852-87a7-d57c9898474f";
                this.SendAsEmailMenuItem.Location = new System.Drawing.Point(2, 76);
                this.SendAsEmailMenuItem.Name = "SendAsEmailMenuItem";
                this.SendAsEmailMenuItem.Size = new System.Drawing.Size(138, 23);
                this.SendAsEmailMenuItem.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
                    new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.SendTo16)});
                this.SendAsEmailMenuItem.TabIndex = 11;
                this.SendAsEmailMenuItem.Text = "Send as Email...";
                this.SendAsEmailMenuItem.Click += new EventHandler(SendToMenuItem_Click);

                ((System.ComponentModel.ISupportInitialize)(this.PopUpMenu)).EndInit();
            }

            private void UpdateMenuItems(CellContext context)
            {
                cellContext = context;
                grid = (TataGrid)context.Grid;
                rowPos = context.Position.Row;
                isSelected = grid.Selection.IsSelectedRow(rowPos);
                bool orderMatters = Global.CurrentPage.OrderMatters;
                MoveUpMenuItem.Enabled = orderMatters && ((isSelected && grid.CanSelectionMoveUp) ||
                                                        (!isSelected && rowPos > 1));
                MoveDownMenuItem.Enabled = orderMatters &&
                                   ((isSelected && grid.CanSelectionMoveDown) ||
                                    (!isSelected && rowPos < grid.RowsCount - 1));
                InvertRemoveMenuItem.Enabled = (grid.RowsCount > 2) && !grid.AllSelected;

                ColumnHead column = columnHeads[context.Position.Column];

                if (column == TataGrid.Source || column == TataGrid.Destination)
                {
                    SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)grid.GetCell(context.Position);
                    string path = cell.DisplayText;
                    bool fileExists = File.Exists(path);
                    bool directoryExists = Directory.Exists(Path.GetDirectoryName(path));

                    OpenMenuItem.Enabled = fileExists;
                    OpenFileLocationMenuItem.Enabled = directoryExists;
                    SendAsEmailMenuItem.Enabled = fileExists;
                }
                else
                {
                    OpenFileLocationMenuItem.Enabled = false;
                }
            }

            public override void OnMouseUp(SourceGrid.CellContext sender, MouseEventArgs e)
            {
                if (enabled == false)
                {
                    return;
                }

                base.OnMouseUp(sender, e);

                if (e.Button == MouseButtons.Right &&
                    sender.IsEditing() == false)
                {
                    UpdateMenuItems(sender);
                    Elegant.Ui.ContextMenu.ShowContextMenu(this.PopUpMenu, Control.MousePosition);
                }
            }


            private void DoOperation(OperationOnSelection opOnSel, OperationOnRow opOnRow)
            {
                if (isSelected)
                {
                    opOnSel();
                }
                else
                {
                    opOnRow(rowPos);
                }

                //cause the ID column need to be changed, so we call UpdateColumns to do so
                grid.UpdateCells();
            }

            public void RemoveMenuItem_Click(object sender, EventArgs e)
            {
                DoOperation(grid.RemoveSelection, grid.RemoveRow);
            }

            private void InvertRemoveMenuItem_Click(object sender, EventArgs e)
            {
                DoOperation(grid.InvertRemoveSelection, grid.InvertRemoveRow);
            }

            private void MoveUpMenuItem_Click(object sender, EventArgs e)
            {
                DoOperation(grid.MoveUpSelection, grid.MoveUpOneRow);
            }

            private void MoveDownMenuItem_Click(object sender, EventArgs e)
            {
                DoOperation(grid.MoveDownSelection, grid.MoveDownOneRow);
            }

            private string GetFileName()
            {
                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)
                    cellContext.Cell;

                if (cell == null || string.IsNullOrEmpty(cell.DisplayText))
                {
                    return string.Empty;
                }

                return cell.DisplayText;
            }

            private void OpenMenuItem_Click(object sender, EventArgs e)
            {
                Helper.StartFile(GetFileName());
            }

            private void OpenFileLocationMenuItem_Click(object sender, EventArgs e)
            {
                string path = GetFileName();
                if (File.Exists(path))
                {
                    Helper.OpenFileLocation(path);
                }
                else
                {
                    Helper.OpenDirectory(Path.GetDirectoryName(path)); 
                }
            }

            private void SendToMenuItem_Click(object sender, EventArgs e)
            {
                Helper.SendAsEmail(GetFileName());
            }
        }

        private class CheckBoxController : SourceGrid.Cells.Controllers.ControllerBase
        {

            public override void OnClick(CellContext sender, EventArgs e)
            {
                if (Global.MainWindow.Busy)
                {
                    SourceGrid.Cells.CheckBox checkBox = (SourceGrid.Cells.CheckBox)sender.Cell;
                    checkBox.Checked = !checkBox.Checked;
                    return;
                }

                base.OnClick(sender, e);

                TataGrid grid = (TataGrid)sender.Grid;

                CheckBoxColumnHead column = (CheckBoxColumnHead)columnHeads[sender.Position.Column];
                grid.UpdatePdfLetsByColumn(column, sender.Position.Row);
                Global.MainWindow.UpdatePdfLetsFlags();
            }

        }

        private class FormatComboxEditor : SourceGrid.Cells.Editors.ComboBox
        {
            private static PdfCreatorFormat[] formats = new PdfCreatorFormat[] 
                            {   
                                PdfCreatorFormat.PDF, 
                                PdfCreatorFormat.PDF_A, 
                                PdfCreatorFormat.PDF_X 
                            };


            public FormatComboxEditor()
                : base(typeof(PdfCreatorFormat), formats, true)
            {
                this.EditableMode = EditableMode.SingleClick;
                this.Control.DropDownStyle = ComboBoxStyle.DropDownList;
                this.Control.Enter += new EventHandler(Control_Enter);
                this.Control.Leave += new EventHandler(Control_Leave);
            }

            public void Control_Enter(object sender, EventArgs e)
            {
                Global.MainWindow.EnableRibbon(false);
            }

            public void Control_Leave(object sender, EventArgs e)
            {
                Global.MainWindow.EnableRibbon(true);
            }

        }

        private class TooltipController : SourceGrid.Cells.Controllers.ToolTipText
        {
            protected override void ApplyToolTipText(CellContext sender, EventArgs e)
            {
                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)sender.Cell;

                string fileName = cell.DisplayText;
                cell.ToolTipText = global::iPdf.Properties.Resources.FileName + fileName;
                string fileStatusInfo = Helper.NewLine + global::iPdf.Properties.Resources.FileStatus;
                FileStatus fileStatus = Helper.CheckFileStatus(fileName);
                switch (fileStatus)
                {
                    case FileStatus.NotExist:
                        fileStatusInfo += global::iPdf.Properties.Resources.FileNonExistent;
                        break;

                    case FileStatus.InUse:
                        fileStatusInfo += global::iPdf.Properties.Resources.FileNotAccessible;
                        break;

                    case FileStatus.Normal:
                        fileStatusInfo += "Normal";
                        break;
                }

                cell.ToolTipText += fileStatusInfo;

                if (fileStatus == FileStatus.Normal &&
                    FileFormat.PdfFormat.IsOneOf(fileName))
                {
                    string fileProperty = SharpHelper.GetPdfProperties(fileName);
                    cell.ToolTipText += fileProperty;
                }

                base.ApplyToolTipText(sender, e);
            }
        }

        private class ErrorController : SourceGrid.Cells.Controllers.Button
        {
            public override void OnClick(CellContext sender, EventArgs e)
            {
                base.OnClick(sender, e);

                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)sender.Cell;

                TataException exception = (TataException)cell.Tag;
                Helper.ShowError(exception);
            }
        }

        private class PasswordEditor : SourceGrid.Cells.Editors.TextBox
        {
            public PasswordEditor(Type p_Type)
                : base(p_Type)
            {
                this.UseCellViewProperties = false;
                this.Control.PasswordChar = '●';
                this.EditableMode = EditableMode.SingleClick | EditableMode.F2Key;
            }

            public override bool SetCellValue(CellContext cellContext, object p_NewValue)
            {
                PasswordString passwordStr = new PasswordString(
                                        this.Control.Text, this.Control.PasswordChar);

                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)EditCell;
                cell.Value = passwordStr;

                return true;
            }
        }

        #endregion
    }
}
